package util

import models.users.Role
import models.users.EPState
import scala.collection.immutable.HashMap
import scala.collection.immutable.HashSet
import play.mvc.Action
import util.annotations.NamedAction
import play.mvc.Results
import play.api.cache.Cache
import services.ColegioSrv
import scala.util.Random
import models.TienePersona

class PermissionValidator() extends Action[NamedAction]() {

  def call(ctx: play.mvc.Http.Context): play.mvc.Result = {
    val role = Role.valueOf(ctx.session().get("role"))
    if (role == Role.SUPADMIN)
      delegate.call(ctx);
    else {
      val state = ColegioSrv.getColegio(ctx.session().get("idColegio").toLong).getState();
      if (PermissionValidator.validate(state, role, configuration.value()))
        delegate.call(ctx)
      else
        Results.unauthorized("Esta acción no puede ser realizada")
    }
  }
}
object PermissionValidator {

  private val stateRoleAction: HashMap[EPState, HashMap[Role, HashSet[String]]] = HashMap(
    EPState.CONFIG_COLEGIO ->
      HashMap(
        Role.SUPADMIN
          -> HashSet("goNext", "newColegio", "updateGrado"),
        Role.COORDINADOR
          -> HashSet("read"),
        Role.PROFESOR -> HashSet("read"),
        Role.SECRETARIO -> HashSet("read")),
    EPState.CONFIG_PERIODO ->
      HashMap(
        Role.SUPADMIN
          -> HashSet("goNext", "newColegio", "updateGrado"),
        Role.COORDINADOR
          -> HashSet("goNext", "read", "newEstudiante",
            "updateCalendarioAcademico", "newCurso",
            "updateCurso", "deleteCurso", "updateMateriaCurso", "newSecretario", "newProfesor"),

        Role.PROFESOR -> HashSet(),
        Role.SECRETARIO -> HashSet()),
    EPState.MATRICULAS ->
      HashMap(
        Role.SUPADMIN
          -> HashSet("goNext", "newColegio", "updateGrado"),
        Role.COORDINADOR
          -> HashSet("goNext", "newEstudiante", "newCurso", "updateCurso",
            "read", "newMatricula", "newSecretario", "newProfesor"),
        Role.PROFESOR -> HashSet(),
        Role.SECRETARIO -> HashSet()),
    EPState.SUBIDA_NOTAS -> HashMap(
      Role.SUPADMIN -> HashSet("goNext", "updateGrado"),
      Role.COORDINADOR -> HashSet("goNext", "read", "newMatricula", "newEstudiante"),
      Role.PROFESOR -> HashSet("getMisAsignaturas", "read", "getIndicadores",
        "getIndicadoresEstudiantes", "newIndicador",
        "updateIndicador", "deleteIndicador", "newIndicadorEstudiante", "deleteIndicadorEstudiante", "setCalificacionPeriodo", "sendMessage"),
      Role.SECRETARIO -> HashSet()),
    EPState.CIERRE_PERIODO ->
      HashMap(
        Role.SUPADMIN
          -> HashSet("goNext", "newColegio", "updateGrado"),
        Role.COORDINADOR
          -> HashSet("goNext", "read"),
        Role.PROFESOR -> HashSet(),
        Role.SECRETARIO -> HashSet()));
  val permissionsMap = HashSet((for (
    (state, roleMap) <- stateRoleAction;
    (role, actionSet) <- roleMap;
    action <- actionSet
  ) yield (state, role, action)).toList: _*)
  val actionSet = permissionsMap.map(_._3);

  def validate(state: EPState, role: Role, action: String): Boolean = {
    if (!(actionSet contains action))
      throw new Exception("Error de configuracion. La accion " + action + " no existe")

    permissionsMap contains (state, role, action)
  }
  def generateUsername(ac: TienePersona): String = {
    ac.getPersona().getTipoDocumento().name() + ac.getPersona().getDocumento();
  }

  def generatePassword(ac: TienePersona): String = generateUsername(ac);

}

